#ifndef __MEMORYPOOL_CPP__
#define __MEMORYPOOL_CPP__

#include "usertype.h"
#include "memorypool.h"
#include "output.h"
#include "bytearrays.h"
#include <execinfo.h>

using namespace WServer::Output;

static MemoryPool* g_MemoryPool = MemoryPool::instance();
MemoryPool* MemoryPool::s_instance = NULL;

MemoryPool::MemoryPool()
{
	lastpos = 0;
}

void MemoryPool::initMemoryPool()
{
	m_memoryPool.resize(WServer::GData::memorycount);
	pthread_mutex_init(&m_memoryMutex, NULL);
	pthread_mutex_lock(&m_memoryMutex);
	for (int i = 0;i < WServer::GData::memorycount;i++) {
		MemoryPoolData* memorydata = new MemoryPoolData;
		m_memoryPool.push_back(memorydata);
	}
	lastpos = 0;
	pthread_mutex_unlock(&m_memoryMutex);
}

MemoryPool::~MemoryPool()
{
	for (int i = 0;i < m_memoryPool.size();i++) {
		delete m_memoryPool[i];
	}
	pthread_mutex_destroy(&m_memoryMutex);
}

MemoryPool* MemoryPool::instance()
{
	if (s_instance == NULL)
		s_instance = new MemoryPool();
	return s_instance;
}

int MemoryPool::getFreeCount()
{
	int c = 0;
	for (int i = 0;i < m_memoryPool.size();i++) {
		if (m_memoryPool[i]->bstatus == 0) c++;
	}
	return c;
}

int MemoryPool::applyMemoryPool()
{
	pthread_mutex_lock(&m_memoryMutex);
	for (int i = lastpos;i < WServer::GData::memorycount;i++) {
		if (m_memoryPool[i]->bstatus) continue;
		m_memoryPool[i]->bstatus = 1;
		lastpos = i;
		pthread_mutex_unlock(&m_memoryMutex);
		return i;
	}
	for (int i = 0;i < lastpos;i++) {
		if (m_memoryPool[i]->bstatus) continue;
		m_memoryPool[i]->bstatus = 1;
		lastpos = i;
		pthread_mutex_unlock(&m_memoryMutex);
		return i;
	}
	pthread_mutex_unlock(&m_memoryMutex);
	return -1;
}

int MemoryPool::applyMemoryPool(int size)
{
	return -1;
}

void MemoryPool::releaseMemoryPool(int index)
{
	if (index < 0 || index > WServer::GData::memorycount) return;
	pthread_mutex_lock(&m_memoryMutex);
	m_memoryPool[index]->bstatus = 0;
	memset(m_memoryPool[index]->data, 0, MEMORYPOOLSIZE);
	pthread_mutex_unlock(&m_memoryMutex);
}

void MemoryPool::reset(int index)
{
	if (index < 0 || index > WServer::GData::memorycount) return;
	memset(m_memoryPool[index]->data, 0, MEMORYPOOLSIZE);
}

#endif //__MEMORYPOOL_CPP__
